﻿using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Windows.Forms;

namespace TcomInvoice
{
    class DataHelper
    {
        public enum EnumDataDictionaryCode
        {
            Item,
            Unit,
            Paymethod,
            TcomAccount,
            VAT
        }

        private tcomdbEntities _context = new tcomdbEntities();

        public void ApplyChanges()
        {
            _context.SaveChanges();
        }

        public void DeleteInvoiceLine(int invoiceID)
        {
            Invoice invoice = _context.Invoices.First(p => p.ID == invoiceID);
            int count = invoice.InvoiceLines.Count();
            for (int i = 0; i < count; ++i)
            {
                InvoiceLine line = invoice.InvoiceLines.First();
                _context.DeleteObject(line);
            }
        }

        public IEnumerable<Invoice> GetListInvoices()
        {
            return _context.Invoices;
        }

        public IEnumerable<Customer> GetListCustomer()
        {
            return _context.Customers;
        }

        public IEnumerable<DataDictionary> GetDictionary()
        {
            return _context.DataDictionaries.OrderBy(p => p.Code).ThenBy(p => p.Value);
        }

        public IEnumerable<InvoiceLine> GetInvoiceLine()
        {
            return _context.InvoiceLines.OrderBy(p => p.InvoiceID).ThenByDescending(p => p.Invoice.Date);
        }

        public IEnumerable<string> GetSuggestionList(string type)
        {
            switch (type)
            {
                case "Presentative":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.PresentativeName) 
                            select c.PresentativeName).Distinct();
                case "Organization":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.Organization) 
                            select c.Organization).Distinct();
                case "TaxCode":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.TaxCode) 
                            select c.TaxCode).Distinct();
                case "Address":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.Address) 
                            select c.Address).Distinct();
                case "Telephone":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.TelNo) 
                            select c.TelNo).Distinct();
                case "Fax":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.FaxNo) 
                            select c.FaxNo).Distinct();
                case "Paymethod":
                    return (from d in _context.DataDictionaries
                            where !string.IsNullOrEmpty(d.Value) && d.Code == "Paymethod"
                            select d.Value).Distinct();
                case "Account":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.BankAccount) 
                            select c.BankAccount).Distinct();
                case "Branch":
                    return (from c in _context.Customers 
                            where !string.IsNullOrEmpty(c.BankBranch) 
                            select c.BankBranch).Distinct();
                case "Item":
                    return (from d in _context.DataDictionaries
                            where !string.IsNullOrEmpty(d.Value) && d.Code == "Item" 
                            select d.Value).Distinct();
                case "Unit":
                    return (from d in _context.DataDictionaries
                            where !string.IsNullOrEmpty(d.Value) && d.Code == "Unit"
                            select d.Value).Distinct();
                case "TcomAccount":
                    return (from d in _context.DataDictionaries
                            where !string.IsNullOrEmpty(d.Value) && d.Code == "TcomAccount"
                            select d.Value).Distinct();
                case "VAT":
                    return (from d in _context.DataDictionaries
                            where !string.IsNullOrEmpty(d.Value) && d.Code == "VAT"
                            select d.Value).Distinct();

                default:
                    return null;
            }
        }

        private int GenerateCustomerKey()
        {
            try
            {
                var query = from c in _context.Customers select c.CustomerID;
                return query.Max() + 1;
            }
            catch
            {
                return 1;
            }
        }

        private int GenerateInvoiceKey()
        {
            try
            {
                var query = from c in _context.Invoices select c.ID;
                return query.Max() + 1;
            }
            catch
            {
                return 1;
            }
        }

        private int GenerateDataDictionaryKey()
        {
            try
            {
                var query = from c in _context.DataDictionaries select c.ID;
                return query.Max() + 1;
            }
            catch
            {
                return 1;
            }
        }

        public int AddCustomer(string Name, string Org, string TaxCode, string Address, string Payment, string Account, string Branch)
        {
            Customer customer = new Customer();
            customer.CustomerID = GenerateCustomerKey();
            if (!string.IsNullOrEmpty(Name) || !string.IsNullOrEmpty(Org)
                || !string.IsNullOrEmpty(TaxCode) || !string.IsNullOrEmpty(Address)
                || !string.IsNullOrEmpty(Payment) || !string.IsNullOrEmpty(Account)
                || !string.IsNullOrEmpty(Branch))
            {
                customer.PresentativeName = Name;
                customer.Organization = Org;
                customer.TaxCode = TaxCode;
                customer.Address = Address;
                customer.BankAccount = Account;
                customer.BankBranch = Branch;
                _context.AddToCustomers(customer);
                _context.SaveChanges();
            }
            else
            {
                customer.CustomerID = -1;
            }

            return customer.CustomerID;
        }

        public void UpdateCustomer(int currentCustomerID, string Name, string Org, string TaxCode, string Address, string Payment, string Account, string Branch)
        {
            Customer customer = _context.Customers.FirstOrDefault(p => p.CustomerID == currentCustomerID);

            if (customer != null)
            {
                customer.PresentativeName = Name;
                customer.Organization = Org;
                customer.TaxCode = TaxCode;
                customer.Address = Address;
                customer.BankAccount = Account;
                customer.BankBranch = Branch;

                _context.SaveChanges();
            }
        }

        public int AddInvoiceHeader(int? CustomerID, 
            string InvoiceNo, string AccountNo, DateTime InvoiceDate, string PayMethod,
            decimal? SumAmount, decimal? VATPercent, decimal? TotalAmount, bool IsPrinted)
        {
            Invoice invoice = new Invoice();
            invoice.ID = GenerateInvoiceKey();
            invoice.CustomerID = CustomerID;
            invoice.InvoiceNo = InvoiceNo;
            invoice.Date = InvoiceDate;
            invoice.AccNo = AccountNo;
            invoice.PayMethod = PayMethod;
            invoice.TotalAmount = SumAmount;
            invoice.TotalAmountInclVAT = TotalAmount;
            invoice.VATPercent = VATPercent;
            invoice.IsPrinted = IsPrinted;

            _context.AddToInvoices(invoice);
            _context.SaveChanges();

            return invoice.ID;
        }

        public void UpdateInvoiceHeader(int InvoiceID, int? CustomerID, 
            string InvoiceNo, string AccountNo, DateTime InvoiceDate, string PayMethod,
            decimal? SumAmount, decimal? VATPercent, decimal? TotalAmount, bool IsPrinted)
        {
            Invoice invoice = _context.Invoices.First(p => p.ID == InvoiceID);
            invoice.CustomerID = CustomerID;
            invoice.InvoiceNo = InvoiceNo;
            invoice.Date = InvoiceDate;
            invoice.AccNo = AccountNo;
            invoice.PayMethod = PayMethod;
            invoice.TotalAmount = SumAmount;
            invoice.TotalAmountInclVAT = TotalAmount;
            invoice.VATPercent = VATPercent;
            invoice.IsPrinted = IsPrinted;

            _context.SaveChanges();
        }

        public void AddInvoiceLines(int InvoiceID, int LineNo, string ItemName, string Unit, int Quantity, decimal Price, decimal Amount)
        {
            InvoiceLine invLine = new InvoiceLine();            
            invLine.InvoiceID = InvoiceID;
            invLine.LineNo = LineNo;
            invLine.ItemName = ItemName;
            invLine.UnitName = Unit;
            invLine.Quantity = Quantity;
            invLine.Price = Price;
            invLine.Amount = Amount;

            Invoice invoice = _context.Invoices.First(p => p.ID == InvoiceID);
            invoice.InvoiceLines.Add(invLine);
            _context.SaveChanges();
        }

        public void UpdateInvoiceLines(int InvoiceID, int LineNo, string ItemName, string Unit, int Quantity, decimal Price, decimal Amount)
        {
            InvoiceLine invLine = _context.InvoiceLines.First(p => p.InvoiceID == InvoiceID && p.LineNo == LineNo);
            invLine.ItemName = ItemName;
            invLine.UnitName = Unit;
            invLine.Quantity = Quantity;
            invLine.Price = Price;
            invLine.Amount = Amount;

            _context.SaveChanges();
        }

        public void RemoveAllInvoiceLines(int InvoiceID)
        {
            Invoice invoice = _context.Invoices.First(p => p.ID == InvoiceID);
            for (int i = invoice.InvoiceLines.Count; i > 0; --i)
            {
                _context.DeleteObject(invoice.InvoiceLines.FirstOrDefault(p => p.InvoiceID == invoice.ID));
            }
            _context.SaveChanges();
        }

        public void AddDataDictionary(EnumDataDictionaryCode Code, string Value)
        {
            if (string.IsNullOrEmpty(Value)) return;
            string dicCode = Code.ToString();
            if (_context.DataDictionaries.FirstOrDefault(p => p.Code == dicCode && p.Value == Value) == null)
            {
                DataDictionary dic = new DataDictionary();
                dic.ID = GenerateDataDictionaryKey();
                dic.Code = Code.ToString();
                dic.Value = Value;

                _context.AddToDataDictionaries(dic);
                _context.SaveChanges();
            }
        }

        public Invoice LoadInvoiceHeader(int invoiceID)
        {
            return _context.Invoices.FirstOrDefault(p => p.ID == invoiceID);
        }

        public IEnumerable<InvoiceLine> LoadInvoiceLine(int invoiceID)
        {
            return _context.InvoiceLines.Where(p => p.InvoiceID == invoiceID);
        }

        public Customer LoadCustomer(int customerID)
        {
            return _context.Customers.FirstOrDefault(p => p.CustomerID == customerID);
        }
    }

    class SettingsHelper
    {
        public class TcomSettings
        {
            public string SelectedAccount { get; set; }
            public string SelectedPayment { get; set; }
            public string SelectedVAT { get; set; }
        }
        
        public void SaveSettings(TcomSettings setting)
        {
            RegistryKey key = Application.UserAppDataRegistry.CreateSubKey("T-COM Invoice");
            if (!string.IsNullOrEmpty(setting.SelectedAccount))
            {
                key.SetValue("TcomAccount", setting.SelectedAccount);
            }
            if (!string.IsNullOrEmpty(setting.SelectedPayment))
            {
                key.SetValue("Payment", setting.SelectedPayment);
            }
            if (!string.IsNullOrEmpty(setting.SelectedVAT))
            {
                key.SetValue("VATPercent", setting.SelectedVAT);
            }
            key.Close();
        }

        public TcomSettings LoadSetting()
        {
            TcomSettings setting = new TcomSettings();
            RegistryKey key = Application.UserAppDataRegistry.CreateSubKey("T-COM Invoice");
            setting.SelectedAccount = (key.GetValue("TcomAccount") ?? "").ToString();
            setting.SelectedPayment = (key.GetValue("Payment") ?? "").ToString();
            setting.SelectedVAT = (key.GetValue("VATPercent") ?? "").ToString();

            return setting;
        }
    }

    
}
